package me.szlx.thing.parser;

import me.szlx.thing.Thing;
import me.szlx.thing.Trait;
import me.szlx.thing.Traits;
import org.yaml.snakeyaml.Yaml;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class YamlThingParser<T extends Thing> extends AbstractThingParser<T> implements ThingParser<T> {
    private static final String ID = "id";
    private static final String NAME = "name";
    private static final String DESCRIPTION = "description";
    private static final String TRAITS = "traits";
    private static final String VALUE = "value";

    @Override
    protected List<T> doParse(InputStream resource) {
        String prefix = getPrefix();
        int fromPosition = 0;

        Yaml yaml = new Yaml();
        Object object = yaml.load(resource);
        while (prefix != null && fromPosition < prefix.length()) {
            int delimiterIndex = prefix.indexOf('.', fromPosition);
            if (delimiterIndex != -1) {
                if (fromPosition != delimiterIndex) {
                    String thePrefix = prefix.substring(fromPosition, delimiterIndex);
                    try {
                        Map<String, Object> theMap = (Map<String, Object>) object;
                        object = theMap.get(thePrefix);
                    } catch (ClassCastException ex) {
                        logger.debug("不存在指定前缀的资源：{}({})", prefix, thePrefix);
                    }
                }
                fromPosition = delimiterIndex + 1;
            }
        }
        List<Map<String, Object>> thingList = (List<Map<String, Object>>) object;
        return thingList == null ? new ArrayList<>() : thingList.stream()
                .map(t -> createThing(t))
                .filter(t -> t != null)
                .collect(Collectors.toList());
    }

    protected T createThing(Map<String, Object> thingMap) {
        Object code = thingMap.get(ID);
        String name = (String) thingMap.get(NAME);
        List<Map<String, String>> traitList = (List<Map<String, String>>) thingMap.get(TRAITS);
        if (code != null && name != null) {
            String description = (String) thingMap.get(DESCRIPTION);
            Traits traits = traitList == null ? null : Traits.of(traitList.stream().map(t -> creatTrait(t)).filter(t -> t != null).collect(Collectors.toList()).toArray(new Trait[0]));
            return createThing(code, name, description, traits);
        }
        logger.debug("事物的代码和名称不能为null，忽略 {}", thingMap);
        return null;
    }


    protected Trait creatTrait(Map<String, String> traitMap) {
        if (traitMap != null) {
            String name = traitMap.get(NAME);
            String value = traitMap.get(VALUE);
            if (name != null) {
                return createTrait(name, value);
            }
            logger.debug("事物特征的名称不能为null，忽略 {}", traitMap);
        }
        return null;
    }
}
